<template>
  <div>
    <el-row :gutter="20">
      <el-col :span="6" v-loading="state.folderLoading">
        <el-card shadow="never" :body-style="{padding:'0px'}">
          <template #header>
            <div class="card-header">
              <span>一级菜单</span>
              <el-button type="success" size="small" @click="doFolderAdd">新增</el-button>
            </div>
          </template>
          <el-table :data="state.folderList" style="width: 100%" size="small"
                    :row-class-name="doRowCLass(state.folderSelected)">
            <el-table-column prop="title" label="名称">
              <template #default="scope">
                <el-link :underline="false" @click="clickFolderRow(scope.row)">{{ scope.row.title }}</el-link>
              </template>
            </el-table-column>
            <el-table-column prop="icon" label="图标">
              <template #default="scope">
                <el-icon size="small">
                  <component :is="scope.row.icon"></component>
                </el-icon>
              </template>
            </el-table-column>

            <el-table-column prop="title" label="操作">
              <template #default="scope">
                <el-popconfirm
                    cancel-button-type="danger"
                    confirm-button-text="确定"
                    cancel-button-text="取消"
                    @confirm="confirmFolderDelete(scope.row,scope)"
                    title="确认删除吗?">
                  <template #reference>
                    <el-button type="danger" size="small" icon="Delete" class="card-small-btn"></el-button>
                  </template>
                </el-popconfirm>
                <el-button type="success" size="small" icon="Edit" class="card-small-btn"
                           @click="doFolderEdit(scope.row,scope.$index)"></el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-card>
      </el-col>
      <el-col :span="8" v-loading="state.menuLoading">
        <el-card shadow="never" :body-style="{padding:'0px'}">
          <template #header>
            <div class="card-header">
              <span>二级菜单</span>
              <el-button type="success" v-if="state.folderSelected>0" size="small" @click="doMenuAdd">新增</el-button>
            </div>
          </template>
          <el-table :data="state.menuList" style="width: 100%" size="small"
                    :row-class-name="doRowCLass(state.menuSelected)">
            <el-table-column prop="title" label="名称">
              <template #default="scope">
                <el-link @click="clickMenuRow(scope.row)" :underline="false">{{ scope.row.title }}</el-link>
              </template>
            </el-table-column>
            <el-table-column prop="name" label="路由"></el-table-column>
            <el-table-column prop="title" label="操作">
              <template #default="scope">
                <el-popconfirm
                    cancel-button-type="danger"
                    confirm-button-text="确定"
                    cancel-button-text="取消"
                    @confirm="confirmMenuDelete(scope.row,scope)"
                    title="确认删除吗?">
                  <template #reference>
                    <el-button type="danger" size="small" icon="Delete" class="card-small-btn"></el-button>
                  </template>
                </el-popconfirm>
                <el-button type="success" size="small" icon="Edit" class="card-small-btn"
                           @click="doMenuEdit(scope.row,scope.$index)"></el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-card>
      </el-col>
      <el-col :span="10" v-loading="state.permissionLoading">
        <el-card shadow="never" :body-style="{padding:'0px'}">
          <template #header>
            <div class="card-header">
              <span>权限</span>
              <el-button v-if="state.menuSelected>0" type="success" size="small" @click="doSavePermission">保存
              </el-button>
            </div>
          </template>
          <div style="color:#d4d4d4;padding: 10px 5px; font-size: 13px;border-bottom: 1px solid #e4d7ed">
            提示：请先选择二级菜单，然后再分配权限
          </div>
          <el-tree
              ref=permissionTree
              style="max-width: 600px"
              :data="state.permissionList"
              :show-checkbox="true"
              node-key="id"
              default-expand-all
              :expand-on-click-node="false"
              :props="{ class: customNodeClass }"
          />
        </el-card>
      </el-col>
      <el-col></el-col>
      <el-col></el-col>
    </el-row>
  </div>
  <MineDialog :obj="state.folderDialog"/>
  <MineDialog :obj="state.menuDialog"/>
</template>

<script setup>
import {onMounted, reactive, ref} from "vue";
import {ElMessage} from "element-plus"
import _axios from "@/plugin/axios.js";

const state = reactive({
  folderLoading: false,
  folderList: [],
  folderSelected: -1,
  folderDialog: {
    visible: false,
    title: '',
    form: {
      title: '',
      icon: ''
    },
    errors: {
      title: '',
      icon: ''
    },
    icons: [
      {id: 1, name: 'Setting'},
      {id: 2, name: 'Clock'},
      {id: 3, name: 'View'},
      {id: 4, name: 'Operation'}
    ],
    fields: [
      {name: "title", label: '标题', wiget: 'input'},
      {name: "icon", label: "图标", wiget: 'radio_icon'}
    ],
    options: {
      icon: [
        {id: 1, name: 'Setting'},
        {id: 2, name: 'Clock'},
        {id: 3, name: 'View'},
        {id: 4, name: 'Operation'}
      ]
    },
    doSubmit: doFolderSubmit,
  },

  menuLoading: false,
  menuDialog: {
    visible: false,
    title: '二级菜单',
    form: {
      title: '',
      name: ''
    },
    errors: {
      title: '',
      name: ''
    },
    fields: [
      {name: 'title', label: "名称", wiget: 'input'},
      {name: 'name', label: "路由", wiget: 'input'}
    ],
    doSubmit: doMenuSubmit,
  },

  menuSelected: -1,
  editId: -1,
  editIndex: -1,
  menuList: [],
  permissionList: [],
  permissionLoading: false
})

const permissionTree = ref("")

onMounted(() => {
  initFolderList()
})

function initFolderList() {
  state.folderLoading = true
  _axios.get('/api/rbac/folder/').then((res) => {
    if (res.data.code === 0) {
      state.folderLoading = false
      state.folderList = res.data.data
    } else {
      ElMessage.error("加载失败")
    }
  })
}

function doFolderSubmit() {
  state.folderDialog.errors = {}
  if (state.editId === -1) {
    _axios.post('/api/rbac/folder/', state.folderDialog.form).then((res) => {
      if (res.data.code === 0) {
        //1.关闭对话框
        state.folderDialog.visible = false

        //2.加入数据列表
        state.folderList.unshift(res.data.data)

        //3.对话框置空
        for (let key in state.folderDialog.form) {
          state.folderDialog.form[key] = ""
        }

      } else if (res.data.code === 2001) {
        for (let key in res.data.detail) {
          state.folderDialog.errors[key] = res.data.detail[key][0]
        }
      } else {
        ElMessage.error("编辑失败")
      }
    })
  } else {
    _axios.put(`/api/rbac/folder/${state.editId}/`, state.folderDialog.form).then((res) => {
      if (res.data.code === 0) {
        //1.关闭对话框
        state.folderDialog.visible = false

        //2.更新数据列表
        state.folderList[state.editIndex] = res.data.data

        //3.置空对话框
        for (let key in state.folderDialog.form) {
          state.folderDialog.form[key] = ""
        }
        //4.恢复初始值
        state.editId = -1
        state.editIndex = -1

      } else if (res.data.code === 2001) {
        for (let key in res.data.detail) {
          state.folderDialog.errors[key] = res.data.detail[key][0]
        }
      } else {
        ElMessage.error("编辑失败")
      }
    })
  }

}

function doFolderEdit(row, index) {
  state.folderDialog.visible = true
  state.folderDialog.title = '编辑一级菜单'
  state.editId = row.id
  state.editIndex = index
  for (let key in state.folderDialog.form) {
    state.folderDialog.form[key] = row[key]
  }
}

function confirmFolderDelete(row, scope) {
  _axios.delete(`/api/rbac/folder/${row.id}/`).then((res) => {
    if (res.data.code === 0) {
      state.folderList.splice(scope.$index, 1)
      // state.folderList = state.folderList.filter((item) => {
      //   return item.id !== row.id
      // })
      if (row.id === state.folderSelected) {
        state.folderSelected = -1
        state.menuSelected = -1
        state.menuList = []
        state.permissionList = []
      }

      ElMessage.success("删除成功")
    } else {
      ElMessage.error("删除失败")
    }
  })
}

function doFolderAdd() {
  state.folderDialog.visible = true
  state.folderDialog.title = '添加一级菜单'
  state.folderDialog.errors = {}

  for (let key in state.folderDialog.form) {
    state.folderDialog.form[key] = ''
  }
  state.folderDialog.editId = -1
  state.folderDialog.editIndex = -1
}

function clickFolderRow(row) {
  //1.一级菜单ID
  state.folderSelected = row.id

  //2.二级菜单选中状态置空
  state.menuSelected = -1

  state.menuList = []
  //3.权限列表置空
  state.permissionList = []

  state.menuLoading = true
  _axios.get("/api/rbac/menu/", {params: {folder: row.id}}).then((res) => {
    if (res.data.code === 0) {
      state.menuLoading = false
      state.menuList = res.data.data
    } else {
      ElMessage.error("加载失败")
    }
  })
}

function doRowCLass(target) {
  return function ({row}) {
    if (row.id === target) {
      return "row-active"
    }
    return ""
  }

}

function doMenuSubmit() {
  state.menuDialog.errors = {}
  if (state.editId > 0) {
    let form = state.menuDialog.form
    form.folder = state.folderSelected
    _axios.put(`/api/rbac/menu/${state.editId}/`, state.menuDialog.form, {params: {folder: state.folderSelected}}).then((res) => {
      if (res.data.code === 0) {
        state.menuDialog.visible = false
        state.menuList[state.editIndex] = res.data.data
        for (let key in state.menuDialog.form) {
          state.menuDialog.form[key] = ''
        }
        state.editIndex = -1
        state.editId = -1
      } else if (res.data.code === 2001) {
        for (let key in res.data.detail) {
          state.folderDialog.errors[key] = res.data.detail[key][0]
        }
      } else {
        ElMessage.error("编辑失败")
      }
    })
  } else {
    let form = state.menuDialog.form
    form.folder = state.folderSelected
    _axios.post('/api/rbac/menu/', state.menuDialog.form).then((res) => {
      if (res.data.code === 0) {
        state.menuDialog.visible = false
        state.menuList.unshift(res.data.data)
        for (let key in state.menuDialog.form) {
          state.menuDialog.form[key] = ''
        }
      } else if (res.data.code === 2001) {
        for (let key in res.data.detail) {
          state.menuDialog.errors[key] = res.data.detail[key][0]
        }
      } else {
        ElMessage.error("添加失败")
      }
    })
  }

}

function doMenuAdd() {
  state.menuDialog.visible = true
  state.menuDialog.title = '添加二级菜单'
  for (let key in state.menuDialog.form) {
    state.menuDialog.form[key] = ''
  }
  state.menuDialog.errors = {}
  state.editId = -1
  state.editIndex = -1
}

function confirmMenuDelete(row, scope) {
  _axios.delete(`/api/rbac/menu/${row.id}/`).then((res) => {
    if (res.data.code === 0) {
      //state.menuList.splice(scope.$index,1)
      state.menuList = state.menuList.filter((item) => {
        return item.id !== row.id
      })
      if (row.id === state.menuSelected) {
        state.menuSelected = -1
        state.permissionList = []
      }
      ElMessage.success("删除成功")
    } else {
      ElMessage.error("删除失败")
    }
  })
}

function doMenuEdit(row, index) {
  state.menuSelected = row.id
  state.menuDialog.visible = true
  state.menuDialog.title = '编辑二级菜单'
  for (let key in state.menuDialog.form) {
    state.menuDialog.form[key] = row[key]
  }
  state.menuDialog.errors = {}
  state.editId = row.id
  state.editIndex = index
}

function clickMenuRow(row) {
  //1.选中二级菜单
  state.menuSelected = row.id
  //2.置空权限列表
  state.permissionList = []

  state.permissionLoading = true

  _axios.get(`/api/rbac/menu/${row.id}/permission/`).then((res) => {
    if (res.data.code === 0) {
      state.permissionLoading = false
      state.permissionList = res.data.data.total_permission
      permissionTree.value.setCheckedKeys(res.data.data.menu_permission)
    } else {
      ElMessage.error("加载失败")
    }
  })
}

function customNodeClass(data, node) {
  if (data.node_horizontal) {
    return 'is-horizontal'
  }
  return null
}

function doSavePermission() {
  let checkedList = permissionTree.value.getCheckedKeys(true)
  checkedList = checkedList.filter((item) => {
    return typeof item === "number"
  })
  _axios.post(`/api/rbac/menu/${state.menuSelected}/permission/`, {permissions: checkedList}, {params: {folder: state.folderSelected}}).then((res) => {
    if (res.data.code === 0) {
      ElMessage.success("分配成功")
    } else {
      ElMessage.error("分配失败")
    }
  })
}
</script>

<style scoped>
.card-header {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
}

.card-small-btn {
  padding: 0 2px;
  font-size: 12px;
  height: 18px;
  width: 18px;
}
</style>

<style>
.el-table .row-active {
  --el-table-tr-bg-color: var(--el-color-primary-light-9);
}

.el-table .row-active .el-link__inner {
  color: #409eff;
}

.is-horizontal > .el-tree-node__content {
  padding: 10px 0;
}

.el-tree .el-tree-node.is-horizontal > .el-tree-node__children {
  display: flex;
  flex-direction: row;
}

.is-horizontal > .el-tree-node__children > div {
  width: 25%;
}
</style>